package top.lcpsky.flashcards.service;

import static com.google.common.collect.Lists.newArrayList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import lombok.extern.slf4j.Slf4j;
import top.lcpsky.flashcards.dto.StockSimpleInfo;
import top.lcpsky.flashcards.entity.Market;
import top.lcpsky.flashcards.entity.Shares;
import top.lcpsky.flashcards.entity.SharesDaily;
import top.lcpsky.flashcards.util.Converts;
import top.lcpsky.flashcards.util.Dates;
import top.lcpsky.flashcards.util.Pager;

@Slf4j
@Service
public class SinaSharesRepository {
	 public static Pager<StockSimpleInfo> pager = null;
	public static final String SINA_API_URL = "http://hq.sinajs.cn/list=";
	
	private RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory());


	/**
	 * <pre>从新浪获取股票信息，规则如下：<br>
	 * 0：”大秦铁路”，股票名字；
	 * 1：”27.55″，今日开盘价；
	 * 2：”27.25″，昨日收盘价；
	 * 3：”26.91″，当前价格；
	 * 4：”27.55″，今日最高价；
	 * 5：”26.20″，今日最低价；
	 * 6：”26.91″，竞买价，即“买一”报价；
	 * 7：”26.92″，竞卖价，即“卖一”报价；
	 * 8：”22114263″，成交的股票数，由于股票交易以一百股为基本单位，所以在使用时，通常把该值除以一百；
	 * 9：”589824680″，成交金额，单位为“元”，为了一目了然，通常以“万元”为成交金额的单位，所以通常把该值除以一万；
	 * 10：”4695″，“买一”申请4695股，即47手；
	 * 11：”26.91″，“买一”报价；
	 * 12：”57590″，“买二”
	 * 13：”26.90″，“买二”
	 * 14：”14700″，“买三”
	 * 15：”26.89″，“买三”
	 * 16：”14300″，“买四”
	 * 17：”26.88″，“买四”
	 * 18：”15100″，“买五”
	 * 19：”26.87″，“买五”
	 * 20：”3100″，“卖一”申报3100股，即31手；
	 * 21：”26.92″，“卖一”报价
	 * (22, 23), (24, 25), (26,27), (28, 29)分别为“卖二”至“卖四的情况”
	 * 30：”2008-01-11″，日期；
	 * 31：”15:05:32″，时间；</pre>
	 * @param code
	 * @return
	 */
	public SharesDaily remoteGetSharesDaily(String code) {
		log.info("请求股票信息：" + SINA_API_URL + code);
		ResponseEntity<String> resp = restTemplate.getForEntity(SINA_API_URL + code, String.class);
		if (!HttpStatus.OK.equals(resp.getStatusCode()) || !resp.hasBody()) {
			throw new RuntimeException("请求新浪股票信息失败");
		}
		log.info("接收的数据：" + resp.getBody());
		// 逗号隔开
		String[] result = StringUtils.split(StringUtils.substringBetween(resp.getBody(), "=\"", "\""), ",");
		if (result.length < 10) {
			throw new RuntimeException("请求新浪的股票信息格式出现问题");
		}
		for (int i = 0; i < result.length; i++) {
			System.out.println(result[i]);
		}
		SharesDaily daily = new SharesDaily();
		daily.setDay(Dates.now());
		daily.setStartPrice(Converts.toDouble(result[1]));
		daily.setEndPrice(Converts.toDouble(result[3]));
		daily.setLastDayEndPrice(Converts.toDouble(result[2]));
		daily.setTradeNum(Converts.toLong(result[8]));
		daily.setTradeAmount(Converts.toLong(result[9]));
		Shares shares = new Shares();
		shares.setName(result[0]);
		for (Market market : Market.values()) {
			if (StringUtils.contains(code, market.name())) {
				shares.setMarket(market);
				shares.setCode(StringUtils.remove(code, market.name()));
				break;
			}
		}
		daily.setShares(shares);
		return daily;
	}
	
	public SharesDaily getRtInfoByCode(String code) {
		if (StringUtils.isEmpty(code)) {
			return null;
		}else {
			String pre = getStockPre(code);
			code = pre + code;
		}
		return remoteGetSharesDaily(code);
	}

	/**   
	 * @Title: getStockPre   
	 * @Description: TODO(这里用一句话描述这个方法的作用)   
	 * @param: @param code
	 * @param: @return      
	 * @return: String      
	 * @throws   
	 */
	public String getStockPre(String code) {
		String pre="";
		Pattern pattern = Pattern.compile("\\d+");
		Matcher matcher = pattern.matcher(code);
		if(matcher.find()) {
			if (code.startsWith("60")) {
				pre ="sh";
			}else if (code.startsWith("00")) {
				pre ="sz";
			}
		}
		return pre;
	}

	/**   
	 * @Title: getPage   
	 * @param: @param map
	 * @param: @param offset
	 * @param: @param limit
	 * @param: @return      
	 * @return: Pager<Site>      
	 * @throws   
	 */
	public Pager<StockSimpleInfo> getPage(Map map, int pageNo, int size) {
		  if (map == null) {
	            if (pager != null) {
	                return pager;
	            }
	            map = new HashMap<>();
	        }
	        int total = getTotalCount(map);
	        Pager<StockSimpleInfo> page = new Pager<>(total, pageNo, size);
	        map.put("offset", pageNo);
	        map.put("size", size);
	        page.setList(getList(map));
	        if (pager == null) {
	            pager = page;
	        }
	        return page;
	}

	/**   
	 * @Title: getList   
	 * @param: @param map
	 * @param: @return      
	 * @return: List<Site>      
	 * @throws   
	 */
	private List<StockSimpleInfo> getList(Map map) {
		List<String> codesAll = newArrayList();
		String code = (java.lang.String) map.get("code");
		if (code.contains(",")) {
			String[] codeArr = code.split(",");
			for (int i = 0; i < codeArr.length; i++) {
				String c = codeArr[i];
				String pre = getStockPre(c );
				codesAll.add(pre.concat(c));
			}
		}else {
			String pre = getStockPre(code);
			codesAll.add(pre.concat(code));
		}
		List<StockSimpleInfo> res = newArrayList();
		for (String c : codesAll) {
			SharesDaily remoteGetSharesDaily = remoteGetSharesDaily(c);
			StockSimpleInfo	 ssInfo = new StockSimpleInfo(remoteGetSharesDaily);
			res.add(ssInfo);
		}
		return res;
	}

	/**   
	 * @Title: getTotalCount   
	 * @param: @param map
	 * @param: @return      
	 * @return: int      
	 * @throws   
	 */
	private int getTotalCount(Map map) {
		int res = 1;
		String code = (java.lang.String) map.get("code");
		if (code.contains(",")) {
			res = code.split(",").length;
		}
		return res;
	}
}
